Completed
Push — master ( 36261e...adbdec )
by
unknown
14s queued 12s
created

tooltip.js ➔ _jQueryInterface   B

Complexity

Conditions 6

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 14
dl 0
loc 25
rs 8.6666
c 0
b 0
f 0
1
/*!
2
  * Bootstrap tooltip.js v4.6.1 (https://getbootstrap.com/)
3
  * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
  */
6
(function (global, factory) {
7
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) :
8
  typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util'], factory) :
0 ignored issues
show
Bug introduced by
The variable define seems to be never declared. If this is a global, consider adding a /** global: define */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
9
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tooltip = factory(global.jQuery, global.Popper, global.Util));
0 ignored issues
show
Bug introduced by
The variable globalThis seems to be never declared. If this is a global, consider adding a /** global: globalThis */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
Best Practice introduced by
If you intend to check if the variable self is declared in the current environment, consider using typeof self === "undefined" instead. This is safe if the variable is not actually declared.
Loading history...
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
10
})(this, (function ($, Popper, Util) { 'use strict';
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
14
  var $__default = /*#__PURE__*/_interopDefaultLegacy($);
15
  var Popper__default = /*#__PURE__*/_interopDefaultLegacy(Popper);
16
  var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util);
17
18
  function _defineProperties(target, props) {
19
    for (var i = 0; i < props.length; i++) {
20
      var descriptor = props[i];
21
      descriptor.enumerable = descriptor.enumerable || false;
22
      descriptor.configurable = true;
23
      if ("value" in descriptor) descriptor.writable = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
24
      Object.defineProperty(target, descriptor.key, descriptor);
25
    }
26
  }
27
28
  function _createClass(Constructor, protoProps, staticProps) {
29
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
30
    if (staticProps) _defineProperties(Constructor, staticProps);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
31
    return Constructor;
32
  }
33
34
  function _extends() {
35
    _extends = Object.assign || function (target) {
36
      for (var i = 1; i < arguments.length; i++) {
37
        var source = arguments[i];
38
0 ignored issues
show
Comprehensibility introduced by
It seems like you are trying to overwrite a function name here. _extends is already defined in line 37 as a function. While this will work, it can be very confusing.
Loading history...
39
        for (var key in source) {
40
          if (Object.prototype.hasOwnProperty.call(source, key)) {
41
            target[key] = source[key];
42
          }
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
43
        }
44
      }
45
46
      return target;
47
    };
48
49
    return _extends.apply(this, arguments);
50
  }
51
52
  /**
53
   * --------------------------------------------------------------------------
54
   * Bootstrap (v4.6.1): tools/sanitizer.js
55
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
56
   * --------------------------------------------------------------------------
57
   */
58
  var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
59
  var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
60
  var DefaultWhitelist = {
61
    // Global attributes allowed on any supplied element below.
62
    '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
63
    a: ['target', 'href', 'title', 'rel'],
64
    area: [],
65
    b: [],
66
    br: [],
67
    col: [],
68
    code: [],
69
    div: [],
70
    em: [],
71
    hr: [],
72
    h1: [],
73
    h2: [],
74
    h3: [],
75
    h4: [],
76
    h5: [],
77
    h6: [],
78
    i: [],
79
    img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
80
    li: [],
81
    ol: [],
82
    p: [],
83
    pre: [],
84
    s: [],
85
    small: [],
86
    span: [],
87
    sub: [],
88
    sup: [],
89
    strong: [],
90
    u: [],
91
    ul: []
92
  };
93
  /**
94
   * A pattern that recognizes a commonly useful subset of URLs that are safe.
95
   *
96
   * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
97
   */
98
99
  var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
100
  /**
101
   * A pattern that matches safe data URLs. Only matches image, video and audio types.
102
   *
103
   * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
104
   */
105
106
  var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
107
108
  function allowedAttribute(attr, allowedAttributeList) {
109
    var attrName = attr.nodeName.toLowerCase();
110
111
    if (allowedAttributeList.indexOf(attrName) !== -1) {
112
      if (uriAttrs.indexOf(attrName) !== -1) {
113
        return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue));
114
      }
115
116
      return true;
117
    }
118
119
    var regExp = allowedAttributeList.filter(function (attrRegex) {
120
      return attrRegex instanceof RegExp;
121
    }); // Check if a regular expression validates the attribute.
122
123
    for (var i = 0, len = regExp.length; i < len; i++) {
124
      if (regExp[i].test(attrName)) {
125
        return true;
126
      }
127
    }
128
129
    return false;
130
  }
131
132
  function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
133
    if (unsafeHtml.length === 0) {
134
      return unsafeHtml;
135
    }
136
137
    if (sanitizeFn && typeof sanitizeFn === 'function') {
138
      return sanitizeFn(unsafeHtml);
139
    }
140
141
    var domParser = new window.DOMParser();
142
    var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
143
    var whitelistKeys = Object.keys(whiteList);
144
    var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));
145
146
    var _loop = function _loop(i, len) {
147
      var el = elements[i];
148
      var elName = el.nodeName.toLowerCase();
0 ignored issues
show
Unused Code introduced by
The parameter len is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
149
150
      if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {
151
        el.parentNode.removeChild(el);
152
        return "continue";
153
      }
154
155
      var attributeList = [].slice.call(el.attributes); // eslint-disable-next-line unicorn/prefer-spread
156
157
      var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
158
      attributeList.forEach(function (attr) {
159
        if (!allowedAttribute(attr, whitelistedAttributes)) {
160
          el.removeAttribute(attr.nodeName);
161
        }
162
      });
163
    };
164
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
165
    for (var i = 0, len = elements.length; i < len; i++) {
166
      var _ret = _loop(i);
167
168
      if (_ret === "continue") continue;
169
    }
170
0 ignored issues
show
Unused Code introduced by
This continue has no effect on the loop flow and can be removed.
Loading history...
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
171
    return createdDocument.body.innerHTML;
172
  }
173
174
  /**
175
   * Constants
176
   */
177
178
  var NAME = 'tooltip';
179
  var VERSION = '4.6.1';
180
  var DATA_KEY = 'bs.tooltip';
181
  var EVENT_KEY = "." + DATA_KEY;
182
  var JQUERY_NO_CONFLICT = $__default["default"].fn[NAME];
183
  var CLASS_PREFIX = 'bs-tooltip';
184
  var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
185
  var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
186
  var CLASS_NAME_FADE = 'fade';
187
  var CLASS_NAME_SHOW = 'show';
188
  var HOVER_STATE_SHOW = 'show';
189
  var HOVER_STATE_OUT = 'out';
190
  var SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
191
  var SELECTOR_ARROW = '.arrow';
192
  var TRIGGER_HOVER = 'hover';
193
  var TRIGGER_FOCUS = 'focus';
194
  var TRIGGER_CLICK = 'click';
195
  var TRIGGER_MANUAL = 'manual';
196
  var AttachmentMap = {
197
    AUTO: 'auto',
198
    TOP: 'top',
199
    RIGHT: 'right',
200
    BOTTOM: 'bottom',
201
    LEFT: 'left'
202
  };
203
  var Default = {
204
    animation: true,
205
    template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',
206
    trigger: 'hover focus',
207
    title: '',
208
    delay: 0,
209
    html: false,
210
    selector: false,
211
    placement: 'top',
212
    offset: 0,
213
    container: false,
214
    fallbackPlacement: 'flip',
215
    boundary: 'scrollParent',
216
    customClass: '',
217
    sanitize: true,
218
    sanitizeFn: null,
219
    whiteList: DefaultWhitelist,
220
    popperConfig: null
221
  };
222
  var DefaultType = {
223
    animation: 'boolean',
224
    template: 'string',
225
    title: '(string|element|function)',
226
    trigger: 'string',
227
    delay: '(number|object)',
228
    html: 'boolean',
229
    selector: '(string|boolean)',
230
    placement: '(string|function)',
231
    offset: '(number|string|function)',
232
    container: '(string|element|boolean)',
233
    fallbackPlacement: '(string|array)',
234
    boundary: '(string|element)',
235
    customClass: '(string|function)',
236
    sanitize: 'boolean',
237
    sanitizeFn: '(null|function)',
238
    whiteList: 'object',
239
    popperConfig: '(null|object)'
240
  };
241
  var Event = {
242
    HIDE: "hide" + EVENT_KEY,
243
    HIDDEN: "hidden" + EVENT_KEY,
244
    SHOW: "show" + EVENT_KEY,
245
    SHOWN: "shown" + EVENT_KEY,
246
    INSERTED: "inserted" + EVENT_KEY,
247
    CLICK: "click" + EVENT_KEY,
248
    FOCUSIN: "focusin" + EVENT_KEY,
249
    FOCUSOUT: "focusout" + EVENT_KEY,
250
    MOUSEENTER: "mouseenter" + EVENT_KEY,
251
    MOUSELEAVE: "mouseleave" + EVENT_KEY
252
  };
253
  /**
254
   * Class definition
255
   */
256
257
  var Tooltip = /*#__PURE__*/function () {
258
    function Tooltip(element, config) {
259
      if (typeof Popper__default["default"] === 'undefined') {
260
        throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
261
      } // Private
262
263
264
      this._isEnabled = true;
265
      this._timeout = 0;
266
      this._hoverState = '';
267
      this._activeTrigger = {};
268
      this._popper = null; // Protected
269
270
      this.element = element;
271
      this.config = this._getConfig(config);
272
      this.tip = null;
273
274
      this._setListeners();
275
    } // Getters
276
277
278
    var _proto = Tooltip.prototype;
279
280
    // Public
281
    _proto.enable = function enable() {
282
      this._isEnabled = true;
283
    };
284
285
    _proto.disable = function disable() {
286
      this._isEnabled = false;
287
    };
288
289
    _proto.toggleEnabled = function toggleEnabled() {
290
      this._isEnabled = !this._isEnabled;
291
    };
292
293
    _proto.toggle = function toggle(event) {
294
      if (!this._isEnabled) {
295
        return;
296
      }
297
298
      if (event) {
299
        var dataKey = this.constructor.DATA_KEY;
300
        var context = $__default["default"](event.currentTarget).data(dataKey);
301
302
        if (!context) {
303
          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
304
          $__default["default"](event.currentTarget).data(dataKey, context);
305
        }
306
307
        context._activeTrigger.click = !context._activeTrigger.click;
308
309
        if (context._isWithActiveTrigger()) {
310
          context._enter(null, context);
311
        } else {
312
          context._leave(null, context);
313
        }
314
      } else {
315
        if ($__default["default"](this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {
316
          this._leave(null, this);
317
318
          return;
319
        }
320
321
        this._enter(null, this);
322
      }
323
    };
324
325
    _proto.dispose = function dispose() {
326
      clearTimeout(this._timeout);
327
      $__default["default"].removeData(this.element, this.constructor.DATA_KEY);
328
      $__default["default"](this.element).off(this.constructor.EVENT_KEY);
329
      $__default["default"](this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler);
330
331
      if (this.tip) {
332
        $__default["default"](this.tip).remove();
333
      }
334
335
      this._isEnabled = null;
336
      this._timeout = null;
337
      this._hoverState = null;
338
      this._activeTrigger = null;
339
340
      if (this._popper) {
341
        this._popper.destroy();
342
      }
343
344
      this._popper = null;
345
      this.element = null;
346
      this.config = null;
347
      this.tip = null;
348
    };
349
350
    _proto.show = function show() {
351
      var _this = this;
352
353
      if ($__default["default"](this.element).css('display') === 'none') {
354
        throw new Error('Please use show on visible elements');
355
      }
356
357
      var showEvent = $__default["default"].Event(this.constructor.Event.SHOW);
358
359
      if (this.isWithContent() && this._isEnabled) {
360
        $__default["default"](this.element).trigger(showEvent);
361
        var shadowRoot = Util__default["default"].findShadowRoot(this.element);
362
        var isInTheDom = $__default["default"].contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);
363
364
        if (showEvent.isDefaultPrevented() || !isInTheDom) {
365
          return;
366
        }
367
368
        var tip = this.getTipElement();
369
        var tipId = Util__default["default"].getUID(this.constructor.NAME);
370
        tip.setAttribute('id', tipId);
371
        this.element.setAttribute('aria-describedby', tipId);
372
        this.setContent();
373
374
        if (this.config.animation) {
375
          $__default["default"](tip).addClass(CLASS_NAME_FADE);
376
        }
377
378
        var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
379
380
        var attachment = this._getAttachment(placement);
381
382
        this.addAttachmentClass(attachment);
383
384
        var container = this._getContainer();
385
386
        $__default["default"](tip).data(this.constructor.DATA_KEY, this);
387
388
        if (!$__default["default"].contains(this.element.ownerDocument.documentElement, this.tip)) {
389
          $__default["default"](tip).appendTo(container);
390
        }
391
392
        $__default["default"](this.element).trigger(this.constructor.Event.INSERTED);
393
        this._popper = new Popper__default["default"](this.element, tip, this._getPopperConfig(attachment));
394
        $__default["default"](tip).addClass(CLASS_NAME_SHOW);
395
        $__default["default"](tip).addClass(this.config.customClass); // If this is a touch-enabled device we add extra
396
        // empty mouseover listeners to the body's immediate children;
397
        // only needed because of broken event delegation on iOS
398
        // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
399
400
        if ('ontouchstart' in document.documentElement) {
401
          $__default["default"](document.body).children().on('mouseover', null, $__default["default"].noop);
402
        }
403
404
        var complete = function complete() {
405
          if (_this.config.animation) {
406
            _this._fixTransition();
407
          }
408
409
          var prevHoverState = _this._hoverState;
410
          _this._hoverState = null;
411
          $__default["default"](_this.element).trigger(_this.constructor.Event.SHOWN);
412
413
          if (prevHoverState === HOVER_STATE_OUT) {
414
            _this._leave(null, _this);
415
          }
416
        };
417
418
        if ($__default["default"](this.tip).hasClass(CLASS_NAME_FADE)) {
419
          var transitionDuration = Util__default["default"].getTransitionDurationFromElement(this.tip);
420
          $__default["default"](this.tip).one(Util__default["default"].TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
421
        } else {
422
          complete();
423
        }
424
      }
425
    };
426
427
    _proto.hide = function hide(callback) {
428
      var _this2 = this;
429
430
      var tip = this.getTipElement();
431
      var hideEvent = $__default["default"].Event(this.constructor.Event.HIDE);
432
433
      var complete = function complete() {
434
        if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
435
          tip.parentNode.removeChild(tip);
436
        }
437
438
        _this2._cleanTipClass();
439
440
        _this2.element.removeAttribute('aria-describedby');
441
442
        $__default["default"](_this2.element).trigger(_this2.constructor.Event.HIDDEN);
443
444
        if (_this2._popper !== null) {
445
          _this2._popper.destroy();
446
        }
447
448
        if (callback) {
449
          callback();
450
        }
451
      };
452
453
      $__default["default"](this.element).trigger(hideEvent);
454
455
      if (hideEvent.isDefaultPrevented()) {
456
        return;
457
      }
458
459
      $__default["default"](tip).removeClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we remove the extra
460
      // empty mouseover listeners we added for iOS support
461
462
      if ('ontouchstart' in document.documentElement) {
463
        $__default["default"](document.body).children().off('mouseover', null, $__default["default"].noop);
464
      }
465
466
      this._activeTrigger[TRIGGER_CLICK] = false;
467
      this._activeTrigger[TRIGGER_FOCUS] = false;
468
      this._activeTrigger[TRIGGER_HOVER] = false;
469
470
      if ($__default["default"](this.tip).hasClass(CLASS_NAME_FADE)) {
471
        var transitionDuration = Util__default["default"].getTransitionDurationFromElement(tip);
472
        $__default["default"](tip).one(Util__default["default"].TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
473
      } else {
474
        complete();
475
      }
476
477
      this._hoverState = '';
478
    };
479
480
    _proto.update = function update() {
481
      if (this._popper !== null) {
482
        this._popper.scheduleUpdate();
483
      }
484
    } // Protected
485
    ;
486
487
    _proto.isWithContent = function isWithContent() {
488
      return Boolean(this.getTitle());
489
    };
490
491
    _proto.addAttachmentClass = function addAttachmentClass(attachment) {
492
      $__default["default"](this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
493
    };
494
495
    _proto.getTipElement = function getTipElement() {
496
      this.tip = this.tip || $__default["default"](this.config.template)[0];
497
      return this.tip;
498
    };
499
500
    _proto.setContent = function setContent() {
501
      var tip = this.getTipElement();
502
      this.setElementContent($__default["default"](tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle());
503
      $__default["default"](tip).removeClass(CLASS_NAME_FADE + " " + CLASS_NAME_SHOW);
504
    };
505
506
    _proto.setElementContent = function setElementContent($element, content) {
507
      if (typeof content === 'object' && (content.nodeType || content.jquery)) {
508
        // Content is a DOM node or a jQuery
509
        if (this.config.html) {
510
          if (!$__default["default"](content).parent().is($element)) {
511
            $element.empty().append(content);
512
          }
513
        } else {
514
          $element.text($__default["default"](content).text());
515
        }
516
517
        return;
518
      }
519
520
      if (this.config.html) {
521
        if (this.config.sanitize) {
522
          content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);
523
        }
524
525
        $element.html(content);
526
      } else {
527
        $element.text(content);
528
      }
529
    };
530
531
    _proto.getTitle = function getTitle() {
532
      var title = this.element.getAttribute('data-original-title');
533
534
      if (!title) {
535
        title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
536
      }
537
538
      return title;
539
    } // Private
540
    ;
541
542
    _proto._getPopperConfig = function _getPopperConfig(attachment) {
543
      var _this3 = this;
544
545
      var defaultBsConfig = {
546
        placement: attachment,
547
        modifiers: {
548
          offset: this._getOffset(),
549
          flip: {
550
            behavior: this.config.fallbackPlacement
551
          },
552
          arrow: {
553
            element: SELECTOR_ARROW
554
          },
555
          preventOverflow: {
556
            boundariesElement: this.config.boundary
557
          }
558
        },
559
        onCreate: function onCreate(data) {
560
          if (data.originalPlacement !== data.placement) {
561
            _this3._handlePopperPlacementChange(data);
562
          }
563
        },
564
        onUpdate: function onUpdate(data) {
565
          return _this3._handlePopperPlacementChange(data);
566
        }
567
      };
568
      return _extends({}, defaultBsConfig, this.config.popperConfig);
569
    };
570
571
    _proto._getOffset = function _getOffset() {
572
      var _this4 = this;
573
574
      var offset = {};
575
576
      if (typeof this.config.offset === 'function') {
577
        offset.fn = function (data) {
578
          data.offsets = _extends({}, data.offsets, _this4.config.offset(data.offsets, _this4.element));
579
          return data;
580
        };
581
      } else {
582
        offset.offset = this.config.offset;
583
      }
584
585
      return offset;
586
    };
587
588
    _proto._getContainer = function _getContainer() {
589
      if (this.config.container === false) {
590
        return document.body;
591
      }
592
593
      if (Util__default["default"].isElement(this.config.container)) {
594
        return $__default["default"](this.config.container);
595
      }
596
597
      return $__default["default"](document).find(this.config.container);
598
    };
599
600
    _proto._getAttachment = function _getAttachment(placement) {
601
      return AttachmentMap[placement.toUpperCase()];
602
    };
603
604
    _proto._setListeners = function _setListeners() {
605
      var _this5 = this;
606
607
      var triggers = this.config.trigger.split(' ');
608
      triggers.forEach(function (trigger) {
609
        if (trigger === 'click') {
610
          $__default["default"](_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) {
611
            return _this5.toggle(event);
612
          });
613
        } else if (trigger !== TRIGGER_MANUAL) {
614
          var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN;
615
          var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT;
616
          $__default["default"](_this5.element).on(eventIn, _this5.config.selector, function (event) {
617
            return _this5._enter(event);
618
          }).on(eventOut, _this5.config.selector, function (event) {
619
            return _this5._leave(event);
620
          });
621
        }
622
      });
623
624
      this._hideModalHandler = function () {
625
        if (_this5.element) {
626
          _this5.hide();
627
        }
628
      };
629
630
      $__default["default"](this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
631
632
      if (this.config.selector) {
633
        this.config = _extends({}, this.config, {
634
          trigger: 'manual',
635
          selector: ''
636
        });
637
      } else {
638
        this._fixTitle();
639
      }
640
    };
641
642
    _proto._fixTitle = function _fixTitle() {
643
      var titleType = typeof this.element.getAttribute('data-original-title');
644
645
      if (this.element.getAttribute('title') || titleType !== 'string') {
646
        this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
647
        this.element.setAttribute('title', '');
648
      }
649
    };
650
651
    _proto._enter = function _enter(event, context) {
652
      var dataKey = this.constructor.DATA_KEY;
653
      context = context || $__default["default"](event.currentTarget).data(dataKey);
654
655
      if (!context) {
656
        context = new this.constructor(event.currentTarget, this._getDelegateConfig());
657
        $__default["default"](event.currentTarget).data(dataKey, context);
658
      }
659
660
      if (event) {
661
        context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
662
      }
663
664
      if ($__default["default"](context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {
665
        context._hoverState = HOVER_STATE_SHOW;
666
        return;
667
      }
668
669
      clearTimeout(context._timeout);
670
      context._hoverState = HOVER_STATE_SHOW;
671
672
      if (!context.config.delay || !context.config.delay.show) {
673
        context.show();
674
        return;
675
      }
676
677
      context._timeout = setTimeout(function () {
678
        if (context._hoverState === HOVER_STATE_SHOW) {
679
          context.show();
680
        }
681
      }, context.config.delay.show);
682
    };
683
684
    _proto._leave = function _leave(event, context) {
685
      var dataKey = this.constructor.DATA_KEY;
686
      context = context || $__default["default"](event.currentTarget).data(dataKey);
687
688
      if (!context) {
689
        context = new this.constructor(event.currentTarget, this._getDelegateConfig());
690
        $__default["default"](event.currentTarget).data(dataKey, context);
691
      }
692
693
      if (event) {
694
        context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false;
695
      }
696
697
      if (context._isWithActiveTrigger()) {
698
        return;
699
      }
700
701
      clearTimeout(context._timeout);
702
      context._hoverState = HOVER_STATE_OUT;
703
704
      if (!context.config.delay || !context.config.delay.hide) {
705
        context.hide();
706
        return;
707
      }
708
709
      context._timeout = setTimeout(function () {
710
        if (context._hoverState === HOVER_STATE_OUT) {
711
          context.hide();
712
        }
713
      }, context.config.delay.hide);
714
    };
715
716
    _proto._isWithActiveTrigger = function _isWithActiveTrigger() {
717
      for (var trigger in this._activeTrigger) {
718
        if (this._activeTrigger[trigger]) {
719
          return true;
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
720
        }
721
      }
722
723
      return false;
724
    };
725
726
    _proto._getConfig = function _getConfig(config) {
727
      var dataAttributes = $__default["default"](this.element).data();
728
      Object.keys(dataAttributes).forEach(function (dataAttr) {
729
        if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
730
          delete dataAttributes[dataAttr];
731
        }
732
      });
733
      config = _extends({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {});
734
735
      if (typeof config.delay === 'number') {
736
        config.delay = {
737
          show: config.delay,
738
          hide: config.delay
739
        };
740
      }
741
742
      if (typeof config.title === 'number') {
743
        config.title = config.title.toString();
744
      }
745
746
      if (typeof config.content === 'number') {
747
        config.content = config.content.toString();
748
      }
749
750
      Util__default["default"].typeCheckConfig(NAME, config, this.constructor.DefaultType);
751
752
      if (config.sanitize) {
753
        config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);
754
      }
755
756
      return config;
757
    };
758
759
    _proto._getDelegateConfig = function _getDelegateConfig() {
760
      var config = {};
761
762
      if (this.config) {
763
        for (var key in this.config) {
764
          if (this.constructor.Default[key] !== this.config[key]) {
765
            config[key] = this.config[key];
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
766
          }
767
        }
768
      }
769
770
      return config;
771
    };
772
773
    _proto._cleanTipClass = function _cleanTipClass() {
774
      var $tip = $__default["default"](this.getTipElement());
775
      var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
776
777
      if (tabClass !== null && tabClass.length) {
778
        $tip.removeClass(tabClass.join(''));
779
      }
780
    };
781
782
    _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {
783
      this.tip = popperData.instance.popper;
784
785
      this._cleanTipClass();
786
787
      this.addAttachmentClass(this._getAttachment(popperData.placement));
788
    };
789
790
    _proto._fixTransition = function _fixTransition() {
791
      var tip = this.getTipElement();
792
      var initConfigAnimation = this.config.animation;
793
794
      if (tip.getAttribute('x-placement') !== null) {
795
        return;
796
      }
797
798
      $__default["default"](tip).removeClass(CLASS_NAME_FADE);
799
      this.config.animation = false;
800
      this.hide();
801
      this.show();
802
      this.config.animation = initConfigAnimation;
803
    } // Static
804
    ;
805
806
    Tooltip._jQueryInterface = function _jQueryInterface(config) {
807
      return this.each(function () {
808
        var $element = $__default["default"](this);
809
        var data = $element.data(DATA_KEY);
810
811
        var _config = typeof config === 'object' && config;
812
813
        if (!data && /dispose|hide/.test(config)) {
814
          return;
815
        }
816
817
        if (!data) {
818
          data = new Tooltip(this, _config);
819
          $element.data(DATA_KEY, data);
820
        }
821
822
        if (typeof config === 'string') {
823
          if (typeof data[config] === 'undefined') {
824
            throw new TypeError("No method named \"" + config + "\"");
825
          }
826
827
          data[config]();
828
        }
829
      });
830
    };
831
832
    _createClass(Tooltip, null, [{
833
      key: "VERSION",
834
      get: function get() {
835
        return VERSION;
836
      }
837
    }, {
838
      key: "Default",
839
      get: function get() {
840
        return Default;
841
      }
842
    }, {
843
      key: "NAME",
844
      get: function get() {
845
        return NAME;
846
      }
847
    }, {
848
      key: "DATA_KEY",
849
      get: function get() {
850
        return DATA_KEY;
851
      }
852
    }, {
853
      key: "Event",
854
      get: function get() {
855
        return Event;
856
      }
857
    }, {
858
      key: "EVENT_KEY",
859
      get: function get() {
860
        return EVENT_KEY;
861
      }
862
    }, {
863
      key: "DefaultType",
864
      get: function get() {
865
        return DefaultType;
866
      }
867
    }]);
868
869
    return Tooltip;
870
  }();
871
  /**
872
   * jQuery
873
   */
874
875
876
  $__default["default"].fn[NAME] = Tooltip._jQueryInterface;
877
  $__default["default"].fn[NAME].Constructor = Tooltip;
878
879
  $__default["default"].fn[NAME].noConflict = function () {
880
    $__default["default"].fn[NAME] = JQUERY_NO_CONFLICT;
881
    return Tooltip._jQueryInterface;
882
  };
883
884
  return Tooltip;
885
886
}));
887
//# sourceMappingURL=tooltip.js.map
888